﻿using GalaSoft.MvvmLight;
using MCHelp;
using GalaSoft.MvvmLight.Command;
using System;
using System.Collections.ObjectModel;
using MoreEPG.Model;
using Microsoft.MediaCenter.Guide;
using System.Linq;
using System.Windows.Data;
using GalaSoft.MvvmLight.Messaging;
using Wpf.DragDrop;
using System.Windows;
using System.Collections.Generic;
using MoreEPG.Helper;

namespace MoreEPG.ViewModel
{

    public class ChannelConfigModel : ViewModelBase
    {
        private bool ButtonCanExecute = false;
        private static NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger();
        private MCConnection MCCon;
        private Core _Core = Core.Instance;
        /// <summary>
        /// Initializes a new instance of the ChannelConfigModel class.
        /// </summary>
        public ChannelConfigModel()
        {
            this.MCCon = _Core.MCCon;
            FillItems();
            this.InitCommands();
        }

        private void FillItems()
        {
            if (this.MCCon == null)
            {
                #region Dummy Datas

                for (int i = 0; i < 15; i++)
                {
                    GuideChannelInfo newItem = new GuideChannelInfo();
                    newItem.Id = i;
                    newItem.ChannelNum = i;
                    newItem.Name = "ChannelNr." + i.ToString();
                    if (i == 1 || i == 5 || i == 7)
                        newItem.Type = "TV";
                    else if (i == 2 || i == 3 )
                        newItem.Type = "RADIO";
                    else
                        newItem.Type = "UNKNOWN";

                    if (i == 3 || i == 4 || i == 6 || i == 10)
                        newItem.ChannelIsDissabled = true;
                    else
                        newItem.ChannelIsDissabled = false;
                    this.Items.Add(newItem);
                }
                this.CVS.Source = this.Items;
                this.All = true;
                this.CVS.View.Filter = new Predicate<object>(FilterCallback);
                Messenger.Default.Register<bool>(
                this,
                m =>
                {
                    if (this.ButtonCanExecute != m)
                    {
                        this.ButtonCanExecute = m;
                        this.Save.RaiseCanExecuteChanged();
                    }
                });

                #endregion
                return;
            }
            MergedLineup lineup = this.MCCon.MainLineup as MergedLineup;
            Channel[] chans = lineup.GetGridChannels().OrderBy(s => s.ChannelNumber.Number).ToArray();
            foreach (Channel _chan in chans)
            {
                MergedChannel chan = _chan as MergedChannel;
                GuideChannelInfo newItem = new GuideChannelInfo();

                newItem.Id = chan.Id;
                newItem.Name = chan.CallSign;
                newItem.channel = _chan;
                newItem.disableInband = chan.IgnoreInbandSchedule;
                newItem.ChannelIsDissabled = chan.IsBlocked;
                newItem.ChannelNum = chan.Number;
                if ((serviceType)chan.Service.ServiceType == serviceType.TV || (serviceType)chan.Service.ServiceType == serviceType.Unknown)
                {
                    newItem.Type = "TV";
                }
                else if ((serviceType)chan.Service.ServiceType == serviceType.RADIO)
                {
                    newItem.Type = "RADIO";
                }
                else
                {
                    newItem.Type = "UNKNOWN";
                }

                this.Items.Add(newItem);
                
            }
            this.CVS.Source = this.Items;
            this.CVS.View.Filter = new Predicate<object>(FilterCallback);
            Messenger.Default.Register<bool>(
                this,
                m =>
                {
                    if (this.ButtonCanExecute != m)
                    {
                        this.ButtonCanExecute = m;
                        this.Save.RaiseCanExecuteChanged();
                    }
                });
        }

        private void InitCommands()
        {
            this.Save = new RelayCommand(
                 () => OnSave(),
                 () => ButtonCanExecute);
        }

        public RelayCommand Save
        {
            get;
            private set;
        }

        private void OnSave()
        {
            List<Channel> ChannelsToUpdate = new List<Channel>();
            bool flag = false;
            try
            {
                foreach (GuideChannelInfo channel in this.Items)
                {
                    MergedChannel mergedChannel = channel.channel as MergedChannel;
                    if (mergedChannel == null)
                    {
                        this.ButtonCanExecute = false;
                        this.Save.RaiseCanExecuteChanged();
                        return;
                    }
                    if (mergedChannel.CallSign != channel.Name)
                    {
                        mergedChannel.CallSign = channel.Name;
                        flag = true;
                    }

                    if (mergedChannel.IgnoreInbandSchedule != channel.disableInband)
                    {
                        mergedChannel.IgnoreInbandSchedule = channel.disableInband;
                        flag = true;
                    }

                    if (mergedChannel.IsBlocked != channel.ChannelIsDissabled)
                    {
                        UserBlockedState state;
                        if (channel.ChannelIsDissabled)
                        {
                            state = UserBlockedState.Blocked;
                        }
                        else
                        {
                            state = UserBlockedState.Enabled;
                        }
                        mergedChannel.UserBlockedState = state;
                        flag = true;
                    }

                    if (flag)
                    {
                        ChannelsToUpdate.Add(mergedChannel);
                    }

                }
                
                if (ChannelsToUpdate.Count > 0)
                {
                    if (!this.MCCon.SaveChannels(ChannelsToUpdate))
                    {
                        var errmessage = new CustomDialogMessage(this.MCCon.lastError, CustomMessageBoxImage.Error, CustomMessageBoxButton.OK, null);
                        Messenger.Default.Send(errmessage);
                        return;
                    }
                }
                var message = new CustomDialogMessage("Fertig", CustomMessageBoxImage.Information, CustomMessageBoxButton.OK, null);
                Messenger.Default.Send(message);
                this.ButtonCanExecute = false;
                this.Save.RaiseCanExecuteChanged();
            }
            catch (Exception ex)
            {
                logger.ErrorException("Error Save Channels", ex);
                var message = new CustomDialogMessage(ex.Message, CustomMessageBoxImage.Error, CustomMessageBoxButton.OK, null);
                Messenger.Default.Send(message);
            }

           
        }



        public const string CheckedPropertyName = "CheckedInband";
        private bool _CheckedInband = false;
        public bool CheckedInband
        {
            get
            {
                return _CheckedInband;
            }

            set
            {
                if (_CheckedInband == value)
                {
                    return;
                }

                foreach (GuideChannelInfo item in Items)
                {
                    item.disableInband = value;
                }

                _CheckedInband = value;

                // Update bindings, no broadcast
                RaisePropertyChanged(CheckedPropertyName);
                
            }
        }


        public const string CheckedDisabledName = "CheckedDisabled";
        private bool _CheckedDisabled = false;
        public bool CheckedDisabled
        {
            get
            {
                return _CheckedDisabled;
            }

            set
            {
                if (_CheckedDisabled == value)
                {
                    return;
                }

                foreach (GuideChannelInfo item in Items)
                {
                    item.ChannelIsDissabled = value;
                }

                _CheckedDisabled = value;

                // Update bindings, no broadcast
                RaisePropertyChanged(CheckedDisabledName);

            }
        }


        public const string ItemsPropertyName = "Items";
        private ObservableCollection<GuideChannelInfo> _Items = new ObservableCollection<GuideChannelInfo>();

        public ObservableCollection<GuideChannelInfo> Items
        {
            get
            {
                return _Items;
            }

            set
            {
                if (_Items == value)
                {
                    return;
                }

                _Items = value;

                // Update bindings, no broadcast
                RaisePropertyChanged(ItemsPropertyName);


            }
        }

        
        public const string CVSPropertyName = "CVS";
        private CollectionViewSource _CVS = new CollectionViewSource();
        public CollectionViewSource CVS
        {
            get
            {
                return _CVS;
            }

            set
            {
                if (_CVS == value)
                {
                    return;
                }

                
                _CVS = value;

               
                // Update bindings, no broadcast
                RaisePropertyChanged(CVSPropertyName);

                
            }
        }

        
        public const string AllPropertyName = "All";
        private bool _All = true;   
        public bool All
        {
            get
            {
                return _All;
            }

            set
            {
                if (_All == value)
                {
                    return;
                }


                _All = value;

                this.CVS.View.Filter = new Predicate<object>(FilterCallback);
                // Update bindings, no broadcast
                RaisePropertyChanged(AllPropertyName);
              
            }
        }

       
        public const string TVPropertyName = "TV";
        private bool _TV = false;
        public bool TV
        {
            get
            {
                return _TV;
            }

            set
            {
                if (_TV == value)
                {
                    return;
                }


                _TV = value;

                this.CVS.View.Filter = new Predicate<object>(FilterCallback);

                // Update bindings, no broadcast
                RaisePropertyChanged(TVPropertyName);
                
            }
        }

        
        public const string RadioPropertyName = "Radio";
        private bool _Radio = false;
        public bool Radio
        {
            get
            {
                return _Radio;
            }

            set
            {
                if (_Radio == value)
                {
                    return;
                }


                _Radio = value;
                this.CVS.View.Filter = new Predicate<object>(FilterCallback);

                // Update bindings, no broadcast
                RaisePropertyChanged(RadioPropertyName);

            }
        }

        
        public const string HidePropertyName = "Hide";
        private bool _Hide = true;  
        public bool Hide
        {
            get
            {
                return _Hide;
            }

            set
            {
                if (_Hide == value)
                {
                    return;
                }

                _Hide = value;
                this.CVS.View.Filter = new Predicate<object>(FilterCallback);

                // Update bindings, no broadcast
                RaisePropertyChanged(HidePropertyName);

            }
        }

        private bool FilterCallback(object obj)
        {
            GuideChannelInfo item = obj as GuideChannelInfo;
            if (this.All && this.Hide)
            {
                if (!item.ChannelIsDissabled)
                    return true;
            }

            if (this.All && !this.Hide)
            {
                    return true;
            }

            if (this.TV && this.Hide)
            {
                if (item.Type == "TV" && !item.ChannelIsDissabled)
                    return true;
            }

            if (this.TV && !this.Hide)
            {
                if (item.Type == "TV")
                    return true;
            }

            if (this.Radio && this.Hide)
            {
                if (item.Type == "RADIO" && !item.ChannelIsDissabled)
                    return true;
            }

            if (this.Radio && !this.Hide)
            {
                if (item.Type == "RADIO")
                    return true;
            }

            return false;
        }


    }
}